<?php
/**
 * @ClassName: Wechat
 * @Description: 微信相关
 * @author: wyaohu
 * @Date: 2024/9/8 19:41
 * @Version: V1.0.0
 */

namespace app\api\controller;

use app\common\model;
use app\common\enum\UserStatus;
use app\common\logic\WechatLogic;
use app\common\logic\MemberLogic;
use EasyWeChat\Kernel\Exceptions\InvalidConfigException;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Overtrue\Socialite\Exceptions\AuthorizeFailedException;
use think\Db;

class Wechat extends Api
{
    protected $first_leader = '';

    protected function initialize()
    {
        $this->first_leader = env('first_leader');
    }

    /**
     * 公众号登录
     * @return \think\response\Json
     */
    public function mpLogin()
    {
        $code = input('code', '');
        $invite_code = input('invite_code', $this->first_leader);
        $invite_type = input('invite_type', 0);
        $invite_store = input('invite_store', 0);

        $app = WechatLogic::mp();
        if (!$code) { // 如果没有code就请求code
            $redirectUrl = $app->oauth
                ->scopes(['snsapi_userinfo'])
                ->redirect($this->request->url(true));
            return $this->redirect($redirectUrl);
        }

        try {
            $data = $app->oauth->userFromCode($code);
            $openid = $data->getId();

            if ($openid) {
                $userinfo = $data->getTokenResponse();
                $unionid = $userinfo['unionid'] ?? '';
                $nickname = $data['nickname'] ?? '';
                $avatar = $data['avatar'] ?? '';
                $params = [
                    'invite_code' => $invite_code,
                    'invite_type' => $invite_type,
                    'invite_store' => $invite_store,
                ];
                $this->checkUser('h5', $openid, $unionid, $params, '', $nickname, $avatar);
            }
        } catch (GuzzleException|AuthorizeFailedException $e) {
            trace($e);
        }

        return json(['code' => 0, 'msg' => '授权失败']);
    }

    /**
     * 小程序登录(手机号授权登录)
     * @return \think\response\Json
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function wxLogin()
    {
        // 获取code码
        $phone_code = input('phone_code', '');
        $login_code = input('login_code', '');
        $iv = input('iv', '');
        $encryptedData = input('encryptedData', '');
        $invite_code = input('invite_code', $this->first_leader);
        $invite_type = input('invite_type', 0);
        $invite_store = input('invite_store', 0);

        if (empty($phone_code) || empty($login_code) || empty($iv) || empty($encryptedData)) {
            return json(['code' => 0, 'msg' => '缺少用户登录凭证']);
        }
        $logic = new WechatLogic();

        try {
            $session = $logic->getMiniSessionCode($login_code);
//            $res = $logic->getPhoneNumber($phone_code);
//            $mobile = $logic->getPhone($iv,$encryptedData,)
            makelog("授权信息：" . json_encode($session), 'login/wx', '_mini');
//            makelog("授权信息：" . json_encode($res), 'login/wx', '_mini');

            $params = [
                'invite_code' => $invite_code,
                'invite_type' => $invite_type,
                'invite_store' => $invite_store,
            ];
            if ($session['code'] == 1) {
//                $this->checkUser('routine', $session['openid'], $session['unionid'] ?? '', $params, $res['phone']['purePhoneNumber']);
                return json(['code' => 1, 'msg' => '登录成功']);
            } else {
                return json(['code' => 0, 'msg' => '登录失败']);
            }
        } catch (\Exception $e) {
            trace($e);
        }
        return json(['code' => 0, 'msg' => '登录异常']);
    }

    /**
     * 小程序授权登录
     * @return \think\response\Json
     */
    public function miniLogin()
    {
        $code = input('code', '');
        $invite_code = input('invite_code', $this->first_leader);
        $invite_type = input('invite_type', 0);
        $invite_store = input('invite_store', 0);

        if (empty($code)) {
            return json(['code' => 0, 'msg' => '缺少必要参数']);
        }

        try {
            $userinfo = WechatLogic::mini()->auth->session($code);

            if (!$userinfo || !isset($userinfo['openid'])) {
                trace('微信登录失败');
                trace($userinfo);
                return json(['code' => 0, 'msg' => '微信登录失败']);
            }

            $openid = $userinfo['openid']; //用户的小程序 openID
            $unionid = $userinfo['unionid'] ?? '';

            if ($openid) {
                $params = [
                    'invite_code' => $invite_code,
                    'invite_type' => $invite_type,
                    'invite_store' => $invite_store,
                ];
                $this->checkUser('routine', $unionid, $openid, $params);
            }
        } catch (InvalidConfigException $e) {
            trace($e);
        }

        return json(['code' => 0, 'msg' => '授权失败']);
    }

    /**
     * APP登录
     * @return \think\response\Json|void
     */
    public function appLogin()
    {
        $openid = input('openid');
        $unionid = input('unionid');
        $invite_code = input('invite_code', $this->first_leader);
        $invite_type = input('invite_type', 0);
        $invite_store = input('invite_store', 0);

        if (!$openid && !$unionid) {
            return json(['code' => 0, 'msg' => '缺少必要参数']);
        }
        $invite_param = [
            'inviter_id' => $invite_code,
            'invite_type' => $invite_type,
            'invite_store' => $invite_store,
        ];
        $this->checkUser('app', $openid, $unionid, $invite_param);
    }

    /**
     * 苹果登录
     * @return \think\response\Json
     */
    public function applelogin()
    {
        $apple_openid = input('apple_openid'); //用户的openID
        $invite_code = input('invite_code', $this->first_leader);
        $invite_type = input('invite_type', 0);
        $invite_store = input('invite_store', 0);

        if (empty($apple_openid)) {
            $this->error('参数错误');
        }

        $member = model\Member::where("apple_openid", $apple_openid)->find();

        if (!$member) { //登录失败，转到常规登录
            $params = [
                'invite_code' => $invite_code,
                'invite_type' => $invite_type,
                'invite_store' => $invite_store,
            ];
            $this->createMember('apple', $apple_openid, '', $params, '苹果用户');
        }

        if ($member['status'] == 0) {
            return json(['code' => 0, 'msg' => '账号已禁用，请联系管理员', 'token' => '']);
        }

        $token = md5(time() . requestIP() . mt_rand(100, 999));
        $upData = [
            'last_login_time' => date_now(),
            'last_login_ip' => requestIP(),
            'errors' => 0,
            'token' => $token,
        ];
        if (!$member['apple_openid']) {
            $upData['apple_openid'] = $apple_openid;
        }
        model\Member::where('id', $member['id'])->update($upData);

        return json(['code' => 1, 'msg' => '登录成功', 'token' => $token]);
    }

    /**
     * 检查用户是否存在
     * @param $loginType
     * @param $openid
     * @param $unionid
     * @param $invite_param
     * @param $mobile
     * @param $nickname
     * @param $avatar
     * @return \think\response\Json
     */
    private function checkUser($loginType, $openid, $unionid, $invite_param, $mobile = '', $nickname = '', $avatar = '')
    {
        if ($mobile) {
            $member = model\Member::where(['mobile' => $mobile])->find();
            if (!$member) {
                $member = $this->getMemberInfo($loginType, $openid, $unionid);
            }
        } else {
            $member = $this->getMemberInfo($loginType, $openid, $unionid);
        }
        if (!$member) {
            $this->createMember($loginType, $openid, $unionid, $invite_param, '微信用户', $mobile, $nickname, $avatar);
        }

        $token = md5(time() . requestIP() . mt_rand(100, 999));
        $upData = [
            'last_login_time' => date_now(),
            'last_login_ip' => requestIP(),
            'errors' => 0,
            'token' => $token,
        ];
        if ($unionid && !$member['unionid']) {
            $upData['unionid'] = $unionid;
        }
        if ($loginType == 'routine' && !$member['mp_openid']) {
            $upData['mp_openid'] = $openid;
        }
        if ($loginType == 'app' && !$member['app_openid']) {
            $upData['app_openid'] = $openid;
        }
        if ($loginType == 'h5' && !$member['openid']) {
            $upData['openid'] = $openid;
        }
        if ($loginType == 'apple' && !$member['apple_openid']) {
            $upData['apple_openid'] = $openid;
        }
        if ($nickname && empty($member['nickname'])) {
            $upData['nickname'] = $nickname;
        }
        if ($avatar && empty($member['avatar'])) {
            $upData['avatar'] = $avatar;
        }
        model\Member::where('id', $member['id'])->update($upData);

        return json(['code' => 1, 'msg' => '登录成功', 'token' => $token]);
    }

    /**
     * 获取会员信息
     * @param $loginType
     * @param $openid
     * @param $unionid
     * @return model\Member
     */
    private function getMemberInfo($loginType, $openid, $unionid)
    {
        switch ($loginType) {
            case 'routine':
                // 小程序登录
                if ($unionid) {
                    $member = model\Member::where('mp_openid', $openid)->whereOr('unionid', $unionid)->find();
                } else {
                    $member = model\Member::where('mp_openid', $openid)->find();
                }
                break;
            case 'app':
                // APP登录
                if ($unionid) {
                    $member = model\Member::where('app_openid', $openid)->whereOr('unionid', $unionid)->find();
                } else {
                    $member = model\Member::where('app_openid', $openid)->find();
                }
                break;
            case 'apple':
                // 苹果登录
                $member = model\Member::where('apple_openid', $openid)->find();
                break;
            default:
                // 公众号登录
                if ($unionid) {
                    $member = model\Member::where('openid', $openid)->whereOr('unionid', $unionid)->find();
                } else {
                    $member = model\Member::where('openid', $openid)->find();
                }
                break;
        }

        return $member;
    }

    private function createMember($loginType, $openid, $unionid, $invite_param, $user_type, $mobile = '', $nickname = '', $avatar = '')
    {

    }

}